#include "Util.hpp"
#include "HandlerData.hpp"
#include "HttpServer.hpp"
#include "User.hpp"

using namespace wyl;


bool CheckUrlValue(const std::string& url)
{
    size_t pos = url.find("https://blog.csdn.net/");
    if(pos == std::string::npos)
    {
        return false;
    }
    return true;
}


bool CheckNumValue(const std::string& value_nums)
{
    if(value_nums.size() > 3)return false; 
    int num = std::stoi(value_nums); 
    if(num <= 0 || num >= 1000)
    {
        //要求设置正确的数量
        return false;
    } 
    return true;
}

enum ReqErr
{
    PARSE_BODY_ERR = 1,
    URL_ERR = 2,
    NUM_ERR = 3
};

int HandlerReqBody(const std::string& _body,std::string* url, int* num)
{
        //解析正文
    //url=xxx&nums=xxx&subitm=xxxx
    std::string input_url;  //url=xxxx
    std::string part_right;
    //获取url=xxx   和  nums=xxx&subitm=xxxx
    if(!Util::CutString(_body,&input_url,&part_right,"&"))
    {
        logMessage(ERROR, "first CutString error");
        return PARSE_BODY_ERR;
    } 
    //获取nums=xxx 和 subitm=xxxx
    size_t pos = _body.find("&"); 
    if(pos == std::string::npos)
    {
        logMessage(ERROR, "find '&' error");
        return PARSE_BODY_ERR;
    }
    std::string input_nums; //nums=xxxx
    std::string input_subimt; 
    if(!Util::CutString(_body.substr(pos+1),&input_nums,&input_subimt,"&"))
    {
        logMessage(ERROR, "second CutString error");
        return PARSE_BODY_ERR;
    } 
    //获取url和xxxxx
        std::string name_url;
        std::string value_url;
    if(!Util::CutString(input_url,&name_url,&value_url,"="))
    {
        logMessage(ERROR, "input_url CutString error");
        return PARSE_BODY_ERR;
    } 

    //nums=xxx
    std::string name_nums;
    std::string value_nums;
    if(!Util::CutString(input_nums,&name_nums,&value_nums,"="))
    {
        logMessage(ERROR, "input_nums CutString error");
        return PARSE_BODY_ERR;
    } 
    //校验value_url 
    if(!CheckUrlValue(value_url))
    {
        //提示博客地址可能不正确
        return URL_ERR;
    }
    if(!CheckNumValue(value_nums))
    {
        //提示输入的数超出
        return NUM_ERR;
    } 
    *url = value_url;
    *num = atoi(value_nums.c_str());
    return 0;    
}


//处理有正文的报文，也就是动态资源
void Handler(const Request& req,Response& resp)
{
    //1.获取请求正文
    std::string _body = req.GetRequestBody();
    //处理正文
    std::string input_url; //博客的地址
    int num; //要刷的数量
    int ret = HandlerReqBody(_body,&input_url,&num); //成功返回0，且url和num被设置，否则返回错误
    std::string resp_path = WEBROOT; //响应的文件地址
    
    //构建响应
    if(ret == 0)
    {
        //请求正常
        resp.SetErrCode(200);
        resp.SetBody(resp_path +"/ok.html");
        //后台进行处理.....
        
    }
    else if(ret == PARSE_BODY_ERR)
    {
        //构建一个400请求
        resp.SetErrCode(400);
        resp.SetBody(resp_path +"/400.html");
    }else if(ret == URL_ERR)
    {
        //构建一个400请求
         resp.SetErrCode(400);
        resp.SetBody(resp_path + "/URLERR.html");
    }else if(ret == NUM_ERR)
    {
        //构建一个400请求
        resp.SetErrCode(400);
        resp.SetHeader("Content-Type",".html");
        resp.SetBody(resp_path + "/NUMERR.html");
    }
    //发送响应
    logMessage(NORMAL,"Send Response ....");
    resp.Send();
    //resp.SetHeader("Content-Type","text/html"); 
}


int main(int argc , char* argv[])
{

   // std::cout << Decode("https%3a%2f%2fblog.csdn.net%2fLin5200000%3ftype%3dblog") << std::endl;
    /*这里是测试代码
    // std::string request = "GET / HTTP/1.0\r\n";
    // std::string body = "这里是正文部分123456";
    // request += "A: aaa\r\n"; 
    // request += "B: bbb\r\n"; 
    // request += "C: ccc\r\n"; 
    // request += "Content-Length: " + std::to_string(body.size()) + "\r\n";
    // request += "\r\n"; 
    // request += body;
    // std::string line; 
    // wyl:: Request req; 
    // Response resp;
    // req.Parse(request,resp);
    // std::string str = "aaa?111&222"; 
    // std::string sep = "?"; 
    // std::string key , value , key2,value2; 
    // Util::CutString(str,&key,&value,sep); 
    // std::cout << "key :" << key << "   value : " << value <<std::endl;
    // Util::CutString(value,&key2,&value2,"&"); 
    // std::cout << "key2 :" << key2 << "   value2 : " << value2 <<std::endl;
    */

    if(argc != 2)
    {
        std::cout << "Usage :  " << argv[0] << "  serverport" << std::endl;
        exit(USAG_ERR);
    }
    //提取端口
    uint16_t port = atoi(argv[1]);
    wyl::HttpServer httpserver(Handler,port); 
    httpserver.init();
    httpserver.start();

    return 0 ;
}